package com.prj.ufdm.demo.tutorial.thread;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * CountDownLatch 它允许一个或多个线程等待其他线程操作完成之后才执行
 * CountDownLatch 是通过计数器的方式来实现，计数器的初始值为线程的数量。每当一个线程完成了自己的任务之后，就会对计数器减1，
 * 当计数器的值为0时，表示所有线程完成了任务，此时等待在闭锁上的线程才继续执行，从而达到等待其他线程完成任务之后才继续执行的目的。
 * @author Administrator
 *
 */
public class TestCountDownLatch {

	public static void main(String[] args) throws Exception {
		
		/**
		 * 司机和工人
		 * 工人必须等到司机来了才能装货上车
		 * 司机必须得等到所有工人把货物装上车了之后才能把车开走。
		 */
		CountDownLatch driverLatch = new CountDownLatch(1);
        CountDownLatch workerLatch = new CountDownLatch(10);
        ExecutorService executor = Executors.newFixedThreadPool(10);
 
        for(int i=0; i<10; i++) {
            executor.execute(new Worker(driverLatch, workerLatch, "worker" + i));
        }
 
        System.out.println("司机过来了");
 
        driverLatch.countDown();
 
        System.out.println("工人开始搬运物品");
 
        workerLatch.await();
 
        System.out.println("Driver is ready to go.");
 
        executor.shutdown();
	}

}

/**
 * 工人类
 * @author Administrator
 *
 */
class Worker implements Runnable {
	 
    private String workerCode;
 
    private CountDownLatch driverLatch;
    private CountDownLatch workerLatch;
 
    Worker(CountDownLatch driverLatch, CountDownLatch workerLatch, String workerCode) {
        this.driverLatch = driverLatch;
        this.workerLatch = workerLatch;
        this.workerCode = workerCode;
    }
 
    @Override
    public void run() {
        try {
        	driverLatch.await();
        	System.out.println("工人（ " + workerCode + "）搬运物品...");
            workerLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
